é å»¶ã¬ã³ããªã³ã°ãšGãããã¡ã«ãããã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒãç¿åŸããWebGLã®å¯èœæ§ãæå€§éã«åŒãåºããŸããæ¬ã¬ã€ãã¯ãäžçã®éçºè åãã«å æ¬çãªçè§£ãæäŸããŸãã
WebGLã®ç¿åŸïŒGãããã¡ã«ããé å»¶ã¬ã³ããªã³ã°ãšãã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒã®åšå
è¿å¹ŽããŠã§ãã°ã©ãã£ãã¯ã¹ã®äžçã¯é©ç°çãªé²æ©ãéããŠããŸãããŠã§ããã©ãŠã¶ã§3Dã°ã©ãã£ãã¯ã¹ãã¬ã³ããªã³ã°ããããã®æšæºã§ããWebGLã¯ãéçºè ãé åçã§ã€ã³ã¿ã©ã¯ãã£ããªããžã¥ã¢ã«äœéšãåµé ããããšãå¯èœã«ããŸããããã®ã¬ã€ãã§ã¯ãé å»¶ã¬ã³ããªã³ã°ãšããŠç¥ããã匷åãªã¬ã³ããªã³ã°æè¡ãæ·±ãæãäžãããã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒãšGãããã¡ã®èœåãæŽ»çšããŠãå°è±¡çãªããžã¥ã¢ã«å質ãšããã©ãŒãã³ã¹ãå®çŸããæ¹æ³ãæ¢ããŸããããã¯ãäžçäžã®ã²ãŒã éçºè ãããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ã®å°éå®¶ã«ãšã£ãŠäžå¯æ¬ ãªç¥èã§ãã
ã¬ã³ããªã³ã°ãã€ãã©ã€ã³ã®çè§£ïŒåºç€
é å»¶ã¬ã³ããªã³ã°ãæ¢ãåã«ãå€ãã®3Dã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããåŸæ¥ã®æ¹æ³ã§ãããäžè¬çãªãã©ã¯ãŒãã¬ã³ããªã³ã°ãã€ãã©ã€ã³ãçè§£ããããšãéèŠã§ãããã©ã¯ãŒãã¬ã³ããªã³ã°ã§ã¯ãã·ãŒã³å ã®åãªããžã§ã¯ããåå¥ã«ã¬ã³ããªã³ã°ãããŸãããªããžã§ã¯ãããšã«ãã©ã€ãã£ã³ã°èšç®ãã¬ã³ããªã³ã°ããã»ã¹äžã«çŽæ¥å®è¡ãããŸããããã¯ããªããžã§ã¯ãã«åœ±é¿ãäžãããã¹ãŠã®å æºã«å¯ŸããŠãã·ã§ãŒããŒïŒGPUã§å®è¡ãããããã°ã©ã ïŒãæçµçãªè²ãèšç®ããããšãæå³ããŸãããã®ã¢ãããŒãã¯åçŽæå¿«ã§ãããç¹ã«å€æ°ã®å æºãšè€éãªãªããžã§ã¯ããæã€ã·ãŒã³ã§ã¯ãèšç®ã³ã¹ããé«ããªãå¯èœæ§ããããŸããå€ãã®ã©ã€ãã«åœ±é¿ãããå Žåãåãªããžã§ã¯ãã¯è€æ°åã¬ã³ããªã³ã°ãããªããã°ãªããŸããã
ãã©ã¯ãŒãã¬ã³ããªã³ã°ã®éç
- ããã©ãŒãã³ã¹ã®ããã«ããã¯ïŒ åãªããžã§ã¯ããåã©ã€ãã«å¯ŸããŠã©ã€ãã£ã³ã°ãèšç®ãããšãã·ã§ãŒããŒã®å®è¡åæ°ãéåžžã«å€ããªããGPUã«è² æ ãããããŸããããã¯ç¹ã«ãã©ã€ãã®æ°ãå€ãå Žåã«ããã©ãŒãã³ã¹ã«åœ±é¿ããŸãã
- ã·ã§ãŒããŒã®è€éãïŒ æ§ã ãªã©ã€ãã£ã³ã°ã¢ãã«ïŒäŸïŒæ¡æ£ãé¡é¢ãç°å¢å ïŒã圱ã®èšç®ããªããžã§ã¯ãã®ã·ã§ãŒããŒã«çŽæ¥çµã¿èŸŒããšãã·ã§ãŒããŒã³ãŒããè€éã«ãªããç¶æãå°é£ã«ãªãå¯èœæ§ããããŸãã
- æé©åã®èª²é¡ïŒ å€ãã®åçã©ã€ãã倿°ã®è€éãªãªããžã§ã¯ããæã€ã·ãŒã³ã§ãã©ã¯ãŒãã¬ã³ããªã³ã°ãæé©åããã«ã¯ããã©ã¹ã¿ã ã«ãªã³ã°ïŒã«ã¡ã©ã®èŠéå ã«è¡šç€ºããããªããžã§ã¯ãã®ã¿ãæç»ïŒããªã¯ã«ãŒãžã§ã³ã«ãªã³ã°ïŒä»ã®ãªããžã§ã¯ãã«é ããŠãããªããžã§ã¯ããæç»ããªãïŒãªã©ã®é«åºŠãªæè¡ãå¿ èŠã§ãããããã§ãå°é£ãªå ŽåããããŸãã
é å»¶ã¬ã³ããªã³ã°ã®ç޹ä»ïŒãã©ãã€ã ã·ãã
é å»¶ã¬ã³ããªã³ã°ã¯ããã©ã¯ãŒãã¬ã³ããªã³ã°ã®éçã軜æžãã代æ¿ã¢ãããŒããæäŸããŸãããžãªã¡ããªãã¹ãšã©ã€ãã£ã³ã°ãã¹ãåé¢ããã¬ã³ããªã³ã°ããã»ã¹ãåå¥ã®ã¹ããŒãžã«åå²ããŸãããã®åé¢ã«ãããç¹ã«å€æ°ã®å æºãæ±ãå Žåã«ãã©ã€ãã£ã³ã°ãšã·ã§ãŒãã£ã³ã°ãããå¹ççã«åŠçã§ããŸããæ¬è³ªçã«ããžãªã¡ããªãšã©ã€ãã£ã³ã°ã®ã¹ããŒãžãåé¢ããããšã§ãã©ã€ãã£ã³ã°èšç®ãããå¹ççã«ãªããŸãã
é å»¶ã¬ã³ããªã³ã°ã®2ã€ã®äž»èŠãªã¹ããŒãž
- ãžãªã¡ããªãã¹ïŒGãããã¡çæïŒïŒ ãã®æåã®ã¹ããŒãžã§ã¯ãã·ãŒã³å
ã®ãã¹ãŠã®å¯èŠãªããžã§ã¯ããã¬ã³ããªã³ã°ããŸãããæçµçãªãã¯ã»ã«ã«ã©ãŒãçŽæ¥èšç®ãã代ããã«ãåãã¯ã»ã«ã«é¢ããé¢é£æ
å ±ãGãããã¡ïŒãžãªã¡ããªãããã¡ïŒãšåŒã°ããäžé£ã®ãã¯ã¹ãã£ã«æ ŒçŽããŸããGãããã¡ã¯äžéçãªåœ¹å²ãæãããæ§ã
ãªãžãªã¡ããªããã³ãããªã¢ã«ã®ããããã£ãæ ŒçŽããŸããããã«ã¯ä»¥äžãå«ãŸããŸãïŒ
- ã¢ã«ããïŒããŒã¹ã«ã©ãŒïŒïŒ ã©ã€ãã£ã³ã°ããªãç¶æ ã®ãªããžã§ã¯ãã®è²ã
- æ³ç·ïŒ ãµãŒãã§ã¹ã®æ³ç·ãã¯ãã«ïŒãµãŒãã§ã¹ãåããŠããæ¹åïŒã
- äœçœ®ïŒã¯ãŒã«ã空éïŒïŒ ã¯ãŒã«ãå ã§ã®ãã¯ã»ã«ã®3Däœçœ®ã
- ã¹ããã¥ã©ãã¯ãŒ/ã©ããã¹ïŒ ãããªã¢ã«ã®å æ²¢ãç²ããå¶åŸ¡ããããããã£ã
- ãã®ä»ã®ãããªã¢ã«ããããã£ïŒ ã·ã§ãŒããŒãã·ãŒã³ã®èŠä»¶ã«å¿ããŠãã¡ã¿ã«ãã¹ãã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ãªã©ã
- ã©ã€ãã£ã³ã°ãã¹ïŒ Gãããã¡ãçæãããåŸã2çªç®ã®ãã¹ã§ã©ã€ãã£ã³ã°ãèšç®ããŸããã©ã€ãã£ã³ã°ãã¹ã¯ãã·ãŒã³å ã®åå æºãå埩åŠçããŸããåã©ã€ãã«ã€ããŠãGãããã¡ããµã³ããªã³ã°ããŠãã©ã€ãã®åœ±é¿ç¯å²å ã«ããåãã©ã°ã¡ã³ãïŒãã¯ã»ã«ïŒã®é¢é£æ å ±ïŒäœçœ®ãæ³ç·ãã¢ã«ãããªã©ïŒãååŸããŸããã©ã€ãã£ã³ã°èšç®ã¯Gãããã¡ããã®æ å ±ã䜿çšããŠå®è¡ãããæçµçãªè²ã決å®ãããŸãããã®åŸãã©ã€ãã®å¯äžãæçµç»åã«è¿œå ããã广çã«ã©ã€ãã®å¯äžããã¬ã³ããããŸãã
Gãããã¡ïŒé å»¶ã¬ã³ããªã³ã°ã®å¿èéš
Gãããã¡ã¯é å»¶ã¬ã³ããªã³ã°ã®åºç€ã§ããããã¯ãå€ãã®å Žåãã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒã䜿çšããŠåæã«ã¬ã³ããªã³ã°ãããäžé£ã®ãã¯ã¹ãã£ã§ããGãããã¡å ã®åãã¯ã¹ãã£ã¯ãåãã¯ã»ã«ã«é¢ããç°ãªãæ å ±ãæ ŒçŽãããžãªã¡ããªãšãããªã¢ã«ã®ããããã£ã®ãã£ãã·ã¥ãšããŠæ©èœããŸãã
ãã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒïŒGãããã¡ã®åºç€
ãã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒã¯ãè€æ°ã®ãã¯ã¹ãã£ã«åæã«ã¬ã³ããªã³ã°ã§ããéèŠãªWebGLã®æ©èœã§ããåäžã®ã«ã©ãŒãããã¡ïŒãã©ã°ã¡ã³ãã·ã§ãŒããŒã®å žåçãªåºåïŒã«æžã蟌ã代ããã«ãè€æ°ã®ãããã¡ã«æžã蟌ãããšãã§ããŸããããã¯ãã¢ã«ãããæ³ç·ãäœçœ®ããŒã¿ãªã©ãæ ŒçŽããå¿ èŠãããGãããã¡ã®äœæã«æé©ã§ããMRTã䜿çšãããšãåäžã®ã¬ã³ããªã³ã°ãã¹å ã§åããŒã¿ãåå¥ã®ãã¯ã¹ãã£ã¿ãŒã²ããã«åºåã§ããŸããããã«ãããå¿ èŠãªãã¹ãŠã®æ å ±ãäºåã«èšç®ãããåŸã®ã©ã€ãã£ã³ã°ãã¹ã§äœ¿çšããããã«æ ŒçŽãããããããžãªã¡ããªãã¹ãå€§å¹ ã«æé©åãããŸãã
ãªãGãããã¡ã«MRTã䜿çšããã®ãïŒ
- å¹çæ§ïŒ ããŒã¿åéã®ããã ãã«è€æ°ã®ã¬ã³ããªã³ã°ãã¹ãå¿ èŠãšããªããªããŸããGãããã¡ã®ãã¹ãŠã®æ å ±ã¯ãåäžã®ãžãªã¡ããªã·ã§ãŒããŒã䜿çšããŠåäžã®ãã¹ã§æžã蟌ãŸããããã»ã¹ãåçåããŸãã
- ããŒã¿æ§æïŒ é¢é£ããŒã¿ããŸãšããã©ã€ãã£ã³ã°èšç®ãç°¡çŽ åããŸããã©ã€ãã£ã³ã°ã·ã§ãŒããŒã¯ããã¯ã»ã«ã®ã©ã€ãã£ã³ã°ãæ£ç¢ºã«èšç®ããããã«å¿ èŠãªãã¹ãŠã®æ å ±ã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããŸãã
- æè»æ§ïŒ å¿ èŠã«å¿ããŠæ§ã ãªãžãªã¡ããªããã³ãããªã¢ã«ã®ããããã£ãæ ŒçŽããæè»æ§ãæäŸããŸããããã¯ã远å ã®ãããªã¢ã«ããããã£ãã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ãªã©ã®ããå€ãã®ããŒã¿ãå«ãããã«ç°¡åã«æ¡åŒµã§ããé©å¿æ§ã®é«ãæè¡ã§ãã
WebGLã§ã®é å»¶ã¬ã³ããªã³ã°ã®å®è£
WebGLã§é å»¶ã¬ã³ããªã³ã°ãå®è£ ããã«ã¯ãããã€ãã®ã¹ããããå¿ èŠã§ããäž»èŠãªæŠå¿µã説æããããã«ãç°¡ç¥åãããäŸãèŠãŠãããŸããããããã¯æŠèŠã§ããããããžã§ã¯ãã®èŠä»¶ã«ãã£ãŠã¯ãããè€éãªå®è£ ãååšããããšãèŠããŠãããŠãã ããã
1. Gãããã¡ãã¯ã¹ãã£ã®èšå®
Gãããã¡ããŒã¿ãæ ŒçŽããããã«ãäžé£ã®WebGLãã¯ã¹ãã£ãäœæããå¿ èŠããããŸãããã¯ã¹ãã£ã®æ°ãšããããã«æ ŒçŽãããããŒã¿ã¯ãããŒãºã«ãã£ãŠç°ãªããŸããéåžžãå°ãªããšã以äžãå¿ èŠã§ãïŒ
- ã¢ã«ãããã¯ã¹ãã£ïŒ ãªããžã§ã¯ãã®ããŒã¹ã«ã©ãŒãæ ŒçŽããããã
- æ³ç·ãã¯ã¹ãã£ïŒ ãµãŒãã§ã¹ã®æ³ç·ãæ ŒçŽããããã
- äœçœ®ãã¯ã¹ãã£ïŒ ãã¯ã»ã«ã®ã¯ãŒã«ã空éäœçœ®ãæ ŒçŽããããã
- ãªãã·ã§ãã«ãã¯ã¹ãã£ïŒ ã¹ããã¥ã©ãã¯ãŒ/ã©ããã¹ãã¢ã³ããšã³ããªã¯ã«ãŒãžã§ã³ããã®ä»ã®ãããªã¢ã«ããããã£ãæ ŒçŽããããã®ãã¯ã¹ãã£ãå«ããããšãã§ããŸãã
以äžã«ãã¯ã¹ãã£ãäœæããæ¹æ³ã瀺ããŸãïŒJavaScriptãšWebGLã䜿çšãã説æäŸïŒïŒ
```javascript // Get WebGL context const gl = canvas.getContext('webgl2'); // Function to create a texture function createTexture(gl, width, height, internalFormat, format, type, data = null) { const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, data); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.bindTexture(gl.TEXTURE_2D, null); return texture; } // Define the resolution const width = canvas.width; const height = canvas.height; // Create the G-Buffer textures const albedoTexture = createTexture(gl, width, height, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE); const normalTexture = createTexture(gl, width, height, gl.RGBA16F, gl.RGBA, gl.FLOAT); const positionTexture = createTexture(gl, width, height, gl.RGBA32F, gl.RGBA, gl.FLOAT); // Create a framebuffer and attach the textures to it const gBufferFramebuffer = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, gBufferFramebuffer); // Attach the textures to the framebuffer using MRTs (WebGl 2.0) gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, albedoTexture, 0); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, normalTexture, 0); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, positionTexture, 0); // Check for framebuffer completeness const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status !== gl.FRAMEBUFFER_COMPLETE) { console.error('Framebuffer is not complete: ', status); } // Unbind gl.bindFramebuffer(gl.FRAMEBUFFER, null); ```2. MRTã䜿çšãããã¬ãŒã ãããã¡ã®èšå®
WebGL 2.0ã§ã¯ãMRTçšã®ãã¬ãŒã ãããã¡ãèšå®ããã«ã¯ããã©ã°ã¡ã³ãã·ã§ãŒããŒå ã§åãã¯ã¹ãã£ãã©ã®ã«ã©ãŒã¢ã¿ããã¡ã³ãã«ãã€ã³ããããããæå®ããå¿ èŠããããŸãã以äžã«ãã®æ¹æ³ã瀺ããŸãïŒ
```javascript // List of attachments. IMPORTANT: Ensure this matches the number of color attachments in your shader! const attachments = [ gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2 ]; gl.drawBuffers(attachments); ```3. ãžãªã¡ããªãã¹ã·ã§ãŒããŒïŒãã©ã°ã¡ã³ãã·ã§ãŒããŒã®äŸïŒ
ããã§Gãããã¡ãã¯ã¹ãã£ã«æžã蟌ã¿ãŸãããã©ã°ã¡ã³ãã·ã§ãŒããŒã¯é ç¹ã·ã§ãŒããŒããããŒã¿ãåãåããã¬ã³ããªã³ã°ãããåãã¯ã»ã«ã«å¯ŸããŠç°ãªãããŒã¿ãã«ã©ãŒã¢ã¿ããã¡ã³ãïŒGãããã¡ãã¯ã¹ãã£ïŒã«åºåããŸããããã¯ããã©ã°ã¡ã³ãã·ã§ãŒããŒå ã§åç §ããŠããŒã¿ãåºåã§ãã`gl_FragData`ã䜿çšããŠè¡ãããŸãã
```glsl #version 300 es precision highp float; // Input from the vertex shader in vec3 vNormal; in vec3 vPosition; in vec2 vUV; // Uniforms - example uniform sampler2D uAlbedoTexture; // Output to MRTs layout(location = 0) out vec4 outAlbedo; layout(location = 1) out vec4 outNormal; layout(location = 2) out vec4 outPosition; void main() { // Albedo: Fetch from a texture (or calculate based on object properties) outAlbedo = texture(uAlbedoTexture, vUV); // Normal: Pass the normal vector outNormal = vec4(normalize(vNormal), 1.0); // Position: Pass the position (in world space, for instance) outPosition = vec4(vPosition, 1.0); } ```éèŠãªæ³šæïŒ ãã©ã°ã¡ã³ãã·ã§ãŒããŒå ã®`layout(location = 0)`ã`layout(location = 1)`ã`layout(location = 2)`ãã£ã¬ã¯ãã£ãã¯ãååºå倿°ãã©ã®ã«ã©ãŒã¢ã¿ããã¡ã³ãïŒã€ãŸãGãããã¡ãã¯ã¹ãã£ïŒã«æžã蟌ãããæå®ããããã«äžå¯æ¬ ã§ãããããã®çªå·ãããã¯ã¹ãã£ããã¬ãŒã ãããã¡ã«ã¢ã¿ãããããé åºã«å¯Ÿå¿ããŠããããšã確èªããŠãã ããããŸãã`gl_FragData`ã¯éæšå¥šã§ãããWebGL 2.0ã§ã¯`layout(location)`ãMRTåºåãå®çŸ©ããããã®æšå¥šãããæ¹æ³ã§ããããšã«ã泚æããŠãã ããã
4. ã©ã€ãã£ã³ã°ãã¹ã·ã§ãŒããŒïŒãã©ã°ã¡ã³ãã·ã§ãŒããŒã®äŸïŒ
ã©ã€ãã£ã³ã°ãã¹ã§ã¯ãGãããã¡ãã¯ã¹ãã£ãã·ã§ãŒããŒã«ãã€ã³ããããã®äžã«æ ŒçŽãããããŒã¿ã䜿çšããŠã©ã€ãã£ã³ã°ãèšç®ããŸãããã®ã·ã§ãŒããŒã¯ãã·ãŒã³å ã®åå æºãå埩åŠçããŸãã
```glsl #version 300 es precision highp float; // Inputs (from the vertex shader) in vec2 vUV; // Uniforms (G-Buffer textures and lights) uniform sampler2D uAlbedoTexture; uniform sampler2D uNormalTexture; uniform sampler2D uPositionTexture; uniform vec3 uLightPosition; uniform vec3 uLightColor; // Output out vec4 fragColor; void main() { // Sample the G-Buffer textures vec4 albedo = texture(uAlbedoTexture, vUV); vec4 normal = texture(uNormalTexture, vUV); vec4 position = texture(uPositionTexture, vUV); // Calculate the light direction vec3 lightDirection = normalize(uLightPosition - position.xyz); // Calculate the diffuse lighting float diffuse = max(dot(normal.xyz, lightDirection), 0.0); vec3 lighting = uLightColor * diffuse * albedo.rgb; fragColor = vec4(lighting, albedo.a); } ```5. ã¬ã³ããªã³ã°ãšãã¬ã³ãã£ã³ã°
1. ãžãªã¡ããªãã¹ïŒæåã®ãã¹ïŒïŒ ã·ãŒã³ãGãããã¡ã«ã¬ã³ããªã³ã°ããŸããããã«ããããã¬ãŒã ãããã¡ã«ã¢ã¿ããããããã¹ãŠã®ãã¯ã¹ãã£ã«åäžã®ãã¹ã§æžã蟌ãŸããŸãããããè¡ãåã«ã`gBufferFramebuffer`ãã¬ã³ããŒã¿ãŒã²ãããšããŠãã€ã³ãããå¿ èŠããããŸãã`gl.drawBuffers()`ã¡ãœããã¯ããã©ã°ã¡ã³ãã·ã§ãŒããŒå ã®`layout(location = ...)`ãã£ã¬ã¯ãã£ããšçµã¿åãããŠäœ¿çšãããåã¢ã¿ããã¡ã³ãã®åºåãæå®ããŸãã
```javascript gl.bindFramebuffer(gl.FRAMEBUFFER, gBufferFramebuffer); gl.drawBuffers(attachments); // Use the attachments array from before gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear the framebuffer // Render your objects (draw calls) gl.bindFramebuffer(gl.FRAMEBUFFER, null); ```2. ã©ã€ãã£ã³ã°ãã¹ïŒ2çªç®ã®ãã¹ïŒïŒ ç»é¢å šäœãèŠãã¯ã¢ããïŒãŸãã¯ãã«ã¹ã¯ãªãŒã³ã®äžè§åœ¢ïŒãã¬ã³ããªã³ã°ããŸãããã®ã¯ã¢ããã¯ãæçµçã«ã©ã€ãã£ã³ã°ãããã·ãŒã³ã®ã¬ã³ããŒã¿ãŒã²ããã§ãããã®ãã©ã°ã¡ã³ãã·ã§ãŒããŒã§ãGãããã¡ãã¯ã¹ãã£ããµã³ããªã³ã°ããã©ã€ãã£ã³ã°ãèšç®ããŸããã©ã€ãã£ã³ã°ãã¹ãã¬ã³ããªã³ã°ããåã«`gl.disable(gl.DEPTH_TEST);`ãèšå®ããå¿ èŠããããŸããGãããã¡ãçæããããã¬ãŒã ãããã¡ãnullã«èšå®ãããã¹ã¯ãªãŒã³ã¯ã¢ãããã¬ã³ããªã³ã°ããããšãã©ã€ããé©çšãããæçµç»åã衚瀺ãããŸãã
```javascript gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.disable(gl.DEPTH_TEST); // Use the lighting pass shader // Bind the G-Buffer textures to the lighting shader as uniforms gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, albedoTexture); gl.uniform1i(albedoTextureLocation, 0); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, normalTexture); gl.uniform1i(normalTextureLocation, 1); gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, positionTexture); gl.uniform1i(positionTextureLocation, 2); // Draw the quad gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.enable(gl.DEPTH_TEST); ```é å»¶ã¬ã³ããªã³ã°ã®å©ç¹
é å»¶ã¬ã³ããªã³ã°ã¯ããŠã§ãã¢ããªã±ãŒã·ã§ã³ã§3Dã°ã©ãã£ãã¯ã¹ãã¬ã³ããªã³ã°ããããã®åŒ·åãªæè¡ã§ãããããã€ãã®éèŠãªå©ç¹ãæäŸããŸãïŒ
- å¹ççãªã©ã€ãã£ã³ã°ïŒ ã©ã€ãã£ã³ã°èšç®ã¯ãå¯èŠã®ãã¯ã»ã«ã«å¯ŸããŠã®ã¿å®è¡ãããŸããããã«ãããç¹ã«å€ãã®å æºãæ±ãå Žåã«ãå¿ èŠãªèšç®æ°ãåçã«æžå°ããå€§èŠæš¡ãªã°ããŒãã«ãããžã§ã¯ãã«ãšã£ãŠéåžžã«äŸ¡å€ããããŸãã
- ãªãŒããŒãããŒã®åæžïŒ ãžãªã¡ããªãã¹ã¯ããã¯ã»ã«ããšã«ããŒã¿ã1åèšç®ããŠæ ŒçŽããã ãã§æžã¿ãŸããã©ã€ãã£ã³ã°ãã¹ã¯ãåã©ã€ãã«å¯ŸããŠãžãªã¡ããªãåã¬ã³ããªã³ã°ããå¿ èŠãªãã©ã€ãã£ã³ã°èšç®ãé©çšããããããªãŒããŒãããŒãåæžãããŸãã
- ã¹ã±ãŒã©ããªãã£ïŒ é å»¶ã¬ã³ããªã³ã°ã¯ã¹ã±ãŒãªã³ã°ã«åªããŠããŸãããžãªã¡ããªãã¹ã圱é¿ãåããªããããã©ã€ãã远å ããŠãããã©ãŒãã³ã¹ãžã®åœ±é¿ã¯éå®çã§ããã©ã€ãã£ã³ã°ãã¹ããã¿ã€ã«åãã¯ã©ã¹ã¿åã¢ãããŒãã䜿çšããŠèšç®æ°ãæžãããªã©ãããã©ãŒãã³ã¹ãããã«åäžãããããã«æé©åã§ããŸãã
- ã·ã§ãŒããŒã®è€éãã®ç®¡çïŒ Gãããã¡ãããã»ã¹ãæœè±¡åãããããã·ã§ãŒããŒéçºãç°¡çŽ åãããŸããã©ã€ãã£ã³ã°ã®å€æŽã¯ããžãªã¡ããªãã¹ã·ã§ãŒããŒã倿Žããããšãªãå¹ççã«è¡ãããšãã§ããŸãã
課é¡ãšèæ ®äºé
é å»¶ã¬ã³ããªã³ã°ã¯åªããããã©ãŒãã³ã¹äžã®å©ç¹ãæäŸããŸããã課é¡ãèæ ®äºé ã䌎ããŸãïŒ
- ã¡ã¢ãªæ¶è²»ïŒ Gãããã¡ãã¯ã¹ãã£ãæ ŒçŽããã«ã¯ãããªãã®éã®ã¡ã¢ãªãå¿ èŠã§ããããã¯ãé«è§£å床ã®ã·ãŒã³ãã¡ã¢ãªãéãããŠããããã€ã¹ã§ã¯æžå¿µäºé ã«ãªãå¯èœæ§ããããŸããæé©åãããGãããã¡ãã©ãŒãããããå粟床浮åå°æ°ç¹æ°ã®ãããªæè¡ãããã軜æžããã®ã«åœ¹ç«ã¡ãŸãã
- ãšã€ãªã¢ã·ã³ã°ã®åé¡ïŒ ã©ã€ãã£ã³ã°èšç®ã¯ãžãªã¡ããªãã¹ã®åŸã«è¡ãããããããšã€ãªã¢ã·ã³ã°ã®ãããªåé¡ãããé¡èã«ãªãããšããããŸããã¢ã³ããšã€ãªã¢ã·ã³ã°æè¡ã䜿çšããŠããšã€ãªã¢ã·ã³ã°ã®ã¢ãŒãã£ãã¡ã¯ããæžããããšãã§ããŸãã
- éæåºŠã®èª²é¡ïŒ é å»¶ã¬ã³ããªã³ã°ã§éæåºŠãæ±ãããšã¯è€éã«ãªãå¯èœæ§ããããŸããéæãªãªããžã§ã¯ãã¯ç¹å¥ãªåŠçãå¿ èŠã§ãå€ãã®å Žåãå¥ã®ã¬ã³ããªã³ã°ãã¹ãå¿ èŠã«ãªããããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãããããã¯ãéæã¬ã€ã€ãŒã®ãœãŒããå«ã远å ã®è€éãªè§£æ±ºçãå¿ èŠã«ãªãããšããããŸãã
- å®è£ ã®è€éãïŒ é å»¶ã¬ã³ããªã³ã°ã®å®è£ ã¯ãäžè¬çã«ãã©ã¯ãŒãã¬ã³ããªã³ã°ãããè€éã§ãããã¬ã³ããªã³ã°ãã€ãã©ã€ã³ãšã·ã§ãŒããŒããã°ã©ãã³ã°ã®ååãªçè§£ãå¿ èŠã§ãã
æé©åæŠç¥ãšãã¹ããã©ã¯ãã£ã¹
é å»¶ã¬ã³ããªã³ã°ã®å©ç¹ãæå€§åããããã«ã以äžã®æé©åæŠç¥ãæ€èšããŠãã ããïŒ
- Gãããã¡ãã©ãŒãããã®æé©åïŒ Gãããã¡ãã¯ã¹ãã£ã«é©ãããã©ãŒããããéžæããããšãéèŠã§ããå¯èœãªå Žåã¯ãäœç²ŸåºŠã®ãã©ãŒãããïŒäŸïŒ`RGBA16F`ã®ä»£ããã«`RGBA32F`ïŒã䜿çšããŠãèŠèŠçãªå質ãå€§å¹ ã«æãªãããšãªãã¡ã¢ãªæ¶è²»ãåæžããŸãã
- ã¿ã€ã«åãŸãã¯ã¯ã©ã¹ã¿åãããé å»¶ã¬ã³ããªã³ã°ïŒ éåžžã«å€æ°ã®ã©ã€ããæã€ã·ãŒã³ã§ã¯ãç»é¢ãã¿ã€ã«ãŸãã¯ã¯ã©ã¹ã¿ã«åå²ããŸããæ¬¡ã«ãåã¿ã€ã«ãŸãã¯ã¯ã©ã¹ã¿ã«åœ±é¿ãäžããã©ã€ããèšç®ããããšã§ãã©ã€ãã£ã³ã°èšç®ãå€§å¹ ã«åæžããŸãã
- é©å¿åæè¡ïŒ ããã€ã¹ã®èœåãšã·ãŒã³ã®è€éãã«å¿ããŠãGãããã¡ã®è§£å床ãã¬ã³ããªã³ã°æŠç¥ãåçã«èª¿æŽããæ©èœãå®è£ ããŸãã
- ãã©ã¹ã¿ã ã«ãªã³ã°ãšãªã¯ã«ãŒãžã§ã³ã«ãªã³ã°ïŒ é å»¶ã¬ã³ããªã³ã°ã䜿çšããŠãããããã®æè¡ã¯äžèŠãªãžãªã¡ããªã®ã¬ã³ããªã³ã°ãé¿ããGPUã®è² è·ã軜æžããããã«äŸç¶ãšããŠæçã§ãã
- æ éãªã·ã§ãŒããŒèšèšïŒ å¹ççãªã·ã§ãŒããŒãäœæããŸããè€éãªèšç®ãé¿ããGãããã¡ãã¯ã¹ãã£ã®ãµã³ããªã³ã°ãæé©åããŸãã
å®äžçã®å¿çšãšäŸ
é å»¶ã¬ã³ããªã³ã°ã¯ãæ§ã ãª3Dã¢ããªã±ãŒã·ã§ã³ã§åºã䜿çšãããŠããŸãã以äžã«ããã€ãã®äŸãæããŸãïŒ
- AAAã²ãŒã ïŒ å€ãã®çŸä»£ã®AAAã²ãŒã ã¯ãé«å質ãªããžã¥ã¢ã«ãå®çŸãã倿°ã®ã©ã€ããè€éãªãšãã§ã¯ãããµããŒãããããã«é å»¶ã¬ã³ããªã³ã°ãæ¡çšããŠããŸããããã«ãããäžçäžã®ãã¬ã€ã€ãŒã楜ããããæ²¡å ¥æã®ããèŠèŠçã«é åçãªã²ãŒã äžçãçãŸããŸãã
- ãŠã§ãããŒã¹ã®3Dããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ïŒ 建ç¯ã補åãã¶ã€ã³ãç§åŠã·ãã¥ã¬ãŒã·ã§ã³ã§äœ¿çšãããã€ã³ã¿ã©ã¯ãã£ããª3Dããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ã¯ããã°ãã°é å»¶ã¬ã³ããªã³ã°ã䜿çšããŸãããã®æè¡ã«ããããŠãŒã¶ãŒã¯ãŠã§ããã©ãŠã¶å ã§éåžžã«è©³çްãª3Dã¢ãã«ãã©ã€ãã£ã³ã°å¹æãšå¯Ÿè©±ã§ããŸãã
- 3Dã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒïŒ è»ãå®¶å ·ãªã©ã®è£œåã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒã¯ããªã¢ã«ãªã©ã€ãã£ã³ã°å¹æãåå°ãå«ããªã¢ã«ã¿ã€ã ã®ã«ã¹ã¿ãã€ãºãªãã·ã§ã³ããŠãŒã¶ãŒã«æäŸããããã«ããã°ãã°é å»¶ã¬ã³ããªã³ã°ãå©çšããŸãã
- å»çããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ïŒ å»çã¢ããªã±ãŒã·ã§ã³ã§ã¯ãå»çã¹ãã£ã³ã®è©³çްãªèª¿æ»ãšåæãå¯èœã«ããããã«3Dã¬ã³ããªã³ã°ã®äœ¿çšãå¢ããŠãããäžçäžã®ç ç©¶è ãèšåºå»ã«å©çããããããŠããŸãã
- ç§åŠã·ãã¥ã¬ãŒã·ã§ã³ïŒ ç§åŠã·ãã¥ã¬ãŒã·ã§ã³ã¯ãæç¢ºã§èª¬æçãªããŒã¿ããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ãæäŸããããã«é å»¶ã¬ã³ããªã³ã°ã䜿çšãããã¹ãŠã®åœã ã§ç§åŠççºèŠã𿢿±ãæ¯æŽããŠããŸãã
äŸïŒè£œåã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒ
ãªã³ã©ã€ã³ã®èªåè»ã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒãæ³åããŠã¿ãŠãã ããããŠãŒã¶ãŒã¯è»ã®å¡è£ è²ãçŽ æãç §ææ¡ä»¶ããªã¢ã«ã¿ã€ã ã§å€æŽã§ããŸããé å»¶ã¬ã³ããªã³ã°ã¯ãããå¹ççã«å®çŸããŸããGãããã¡ã¯è»ã®çŽ æããããã£ãæ ŒçŽããŸããã©ã€ãã£ã³ã°ãã¹ã¯ããŠãŒã¶ãŒå ¥åïŒå€ªéœã®äœçœ®ãç°å¢å ãªã©ïŒã«åºã¥ããŠåçã«ã©ã€ãã£ã³ã°ãèšç®ããŸããããã«ããããã©ããªã¢ãªã¹ãã£ãã¯ãªãã¬ãã¥ãŒãäœæãããããã¯ããããã°ããŒãã«ãªè£œåã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒã«ãšã£ãŠéèŠãªèŠä»¶ã§ãã
WebGLãšé å»¶ã¬ã³ããªã³ã°ã®æªæ¥
WebGLã¯ãããŒããŠã§ã¢ãšãœãããŠã§ã¢ã®ç¶ç¶çãªæ¹åãšãšãã«é²åãç¶ããŠããŸããWebGL 2.0ãããåºãæ¡çšãããã«ã€ããŠãéçºè ã¯ããã©ãŒãã³ã¹ãšæ©èœã®é¢ã§åäžããèœåãç®ã®åœããã«ããã§ããããé å»¶ã¬ã³ããªã³ã°ãé²åããŠããŸããæ°ããªãã¬ã³ãã«ã¯ä»¥äžã®ãããªãã®ããããŸãïŒ
- æé©åæè¡ã®åäžïŒ ã¡ã¢ãªãããããªã³ããåæžããããã©ãŒãã³ã¹ãåäžãããããã®ããå¹ççãªæè¡ãåžžã«éçºãããŠãããäžçäžã®ãã¹ãŠã®ããã€ã¹ããã©ãŠã¶ã§ãããã«è©³çްãªè¡šçŸãå¯èœã«ãªããŸãã
- æ©æ¢°åŠç¿ãšã®çµ±åïŒ 3Dã°ã©ãã£ãã¯ã¹ã®äžçã§æ©æ¢°åŠç¿ãç»å ŽããŠããŸããããã«ãããããã€ã³ããªãžã§ã³ããªã©ã€ãã£ã³ã°ãæé©åãå¯èœã«ãªãå¯èœæ§ããããŸãã
- é«åºŠãªã·ã§ãŒãã£ã³ã°ã¢ãã«ïŒ ããã«ãªã¢ãªãºã ã远æ±ãããããæ°ããã·ã§ãŒãã£ã³ã°ã¢ãã«ãåžžã«å°å ¥ãããŠããŸãã
çµè«
é å»¶ã¬ã³ããªã³ã°ã¯ããã«ãã¬ã³ããŒã¿ãŒã²ããïŒMRTïŒãšGãããã¡ã®åãšçµã¿åãããããšã§ãéçºè ãWebGLã¢ããªã±ãŒã·ã§ã³ã§åè¶ããããžã¥ã¢ã«å質ãšããã©ãŒãã³ã¹ãéæããããšãå¯èœã«ããŸãããã®ã¬ã€ãã§èª¬æãããã®æè¡ã®åºç€ãçè§£ãããã¹ããã©ã¯ãã£ã¹ãé©çšããããšã§ãäžçäžã®éçºè ã¯ããŠã§ãããŒã¹ã®ã°ã©ãã£ãã¯ã¹ã®éçãæŒãåºãããæ²¡å ¥åã§ã€ã³ã¿ã©ã¯ãã£ããª3Däœéšãåµé ã§ããŸãããããã®æŠå¿µãç¿åŸããããšã§ãå°ççãªå Žæãç¹å®ã®éçºç®æšã«é¢ä¿ãªããWebGL 3Dã¬ã³ããªã³ã°ãå«ããããããããžã§ã¯ãã«ãšã£ãŠéåžžã«äŸ¡å€ã®ãããèŠèŠçã«é åçã§é«åºŠã«æé©åãããã¢ããªã±ãŒã·ã§ã³ãæäŸã§ããŸãã
ææŠãåãå ¥ããå¯èœæ§ãæ¢æ±ããçµ¶ããé²åãããŠã§ãã°ã©ãã£ãã¯ã¹ã®äžçã«è²¢ç®ããŠãã ããïŒ